/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Discribe：日志重定向
* CreateTime：2020-04-05 19:05:41
* Version：1.0
* Modify Recoder：
*************************************************/
using System;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditorInternal;
using UnityEngine;

namespace TinyToolKit.Editor
{
    public static class LogRedirection
    {
        private static readonly Regex LogRegex = new Regex(@" \(at (.+)\:(\d+)\)\r?\n");

        //打开资产的回调属性
        [OnOpenAsset(0)]
        private static bool OnOpenAsset(int instanceID,int line)
        {
            string selectedStackTrace = GetSelectedStackTrace();
            if (string.IsNullOrEmpty(selectedStackTrace)) return false;

            //通过stacktrace来定位是否是自定义的TLogTool
            //一层一层定位，直到打印日志的脚本路径
            if (selectedStackTrace.Contains("TinyToolKit.DefaultLogTemplate:Log") == false) return false;

            Match match = LogRegex.Match(selectedStackTrace);
            if (match.Success == false) return false;

            if (match.Groups[1].Value.Contains("DefaultLogTemplate.cs"))
            {
                match = match.NextMatch();
                if (match.Success == false) return false;
            }

            if(match.Groups[1].Value.Contains("TLogTool.cs"))
            {
                match = match.NextMatch();
                if (match.Success == false) return false;
            }

            //打开定位后的脚本路径
            string fileName = Path.Combine(Application.dataPath, match.Groups[1].Value.Substring(7));
            int lineNum = int.Parse(match.Groups[2].Value);
            InternalEditorUtility.OpenFileAtLineExternal(fileName,lineNum);
            return true;
        }

        private static string GetSelectedStackTrace()
        {
            //获取UnityEditor.EditorWindow的Assembly
            Assembly editorWindowAssembly = Assembly.GetAssembly(typeof(EditorWindow));
            if (editorWindowAssembly == null) return null;

            //获取UnityEditor.ConsoleWindow
            Type consoleWindowType = editorWindowAssembly.GetType("UnityEditor.ConsoleWindow");
            if (consoleWindowType == null) return null;

            //获取ConsoleWindow中的字段ms_ConsoleWindow
            FieldInfo consoleWindowFieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);
            if (consoleWindowFieldInfo == null) return null;

            //获取ms_ConsoleWindow的值
            EditorWindow consoleWindow = consoleWindowFieldInfo.GetValue(null) as EditorWindow;
            if (consoleWindow == null) return null;

            //如果Console窗口当前不是焦点窗口，则返回
            if (consoleWindow != EditorWindow.focusedWindow) return null;

            //获取ConsoleWindow中的字段m_ActiveText
            FieldInfo activeTextFieldInfo = consoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);
            if (activeTextFieldInfo == null) return null;

            string activeText = activeTextFieldInfo.GetValue(consoleWindow).ToString();

            return activeText;
        }
    }
}